#ifndef LOGSYS_C
#define LOGSYS_C
#include "logsys.h"

#define BUFFER_LENGTH 64
#define FILE_NAME_LENGTH 1024

#define VERSTR "LOGv0.1"

static pthread_rwlock_t *rwlock=NULL;

static char file_name[FILE_NAME_LENGTH];
static Log_Data buffer[BUFFER_LENGTH];
static int buffer_pos=-1;

#define CLEAR_BUFFER() memset(buffer,0,sizeof(Log_Data)*BUFFER_LENGTH)


static void tm2date(struct tm *tm,Date *d)
{
	d->year=tm->tm_year+1900;
	d->month=tm->tm_mon+1;
	d->day=tm->tm_mday;
	d->hour=tm->tm_hour;
	d->mins=tm->tm_min;
}

static int Sync_Buffer(END_TYPE type)
{
	FILE *fp;
	Log_Head tmp;
	time_t cur_time;
	cur_time=time(NULL);
	if(Api_Logsys_ReadLog(file_name,&tmp)==0)
		return 0;
	
	pthread_rwlock_wrlock(rwlock);
	
	if((fp=fopen(file_name,"wb"))==NULL)
		return 0;
	tmp.datacount+=buffer_pos+1;
	tmp.end_type=type;
	tm2date(localtime(&cur_time),&tmp.end_time);
	fwrite(&tmp,sizeof(Log_Head),1,fp);
	fclose(fp);
	if((fp=fopen(file_name,"ab+"))==NULL)
		return 0;
	fwrite(buffer,sizeof(Log_Data),buffer_pos+1,fp);
	fclose(fp);
	pthread_rwlock_unlock(rwlock);
	buffer_pos=-1;
	DBGINFO("I am sync!!\n");
	return 1;
}

void Api_Logsys_StartLog(Log_Data setting_data,U64 worktime)
{
	FILE *fp;
	time_t cur_time;
	cur_time=time(NULL);
	Log_Head head;
	head.end_type=SYS_ERROR;
	tm2date(localtime(&cur_time),&head.start_time);
	tm2date(localtime(&cur_time),&head.end_time);
	memcpy(&head.setting_data,&setting_data,sizeof(Log_Data));
	head.worktime=worktime;
	head.datacount=0;
	memset(head.ver,0,8);
	sprintf(head.ver,"%s",VERSTR);
	memset(file_name,0,FILE_NAME_LENGTH);
	sprintf(file_name, "%d.log", (int)cur_time);
	pthread_rwlock_wrlock(rwlock);
	fp=fopen(file_name,"wb");
	fwrite(&head,sizeof(head),1,fp);
	fclose(fp);
	pthread_rwlock_unlock(rwlock);
}

void Api_Logsys_AddData(Log_Data data)
{
	buffer_pos+=1;
	DBGINFO("buffer_pos:%d\n",buffer_pos);
	if(buffer_pos>(BUFFER_LENGTH-1))
		Sync_Buffer(SYS_ERROR);
	buffer[buffer_pos].humi=data.humi;
	buffer[buffer_pos].temper=data.temper;
}

void Api_Logsys_EndLog(END_TYPE type)
{
	Sync_Buffer(type);
}

int Api_Logsys_ReadLog(char *file,Log_Head *head)
{
	FILE *fp;
	pthread_rwlock_rdlock(rwlock);
	if((fp=fopen(file,"r"))==NULL)
		return 0;
	fread(head,sizeof(Log_Head),1,fp);
	fclose(fp);
	pthread_rwlock_unlock(rwlock);
	if(strcmp(head->ver,VERSTR))
		return 0;
	return 1;
}

int Api_Logsys_ReadData(char *file,U64 pos,Log_Data *data)
{
	FILE *fp;
	Log_Head tmp;
	if(Api_Logsys_ReadLog(file,&tmp)==0) 
		return 0;
	if(pos>tmp.datacount)
		return 0;
	
	pthread_rwlock_rdlock(rwlock);
	if((fp=fopen(file,"r"))==NULL)
		return 0;
	fseek(fp,sizeof(Log_Head)+pos*sizeof(Log_Data),SEEK_SET);
	fread(data,sizeof(Log_Head),1,fp);
	fclose(fp);
	pthread_rwlock_unlock(rwlock);
	return 1;
}

void Api_Logsys_Init()
{
	if(rwlock==NULL){
		rwlock=(pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
		pthread_rwlock_init(rwlock,NULL);
	}
}

void Api_Logsys_Uninit()
{
	if(rwlock){
		pthread_rwlock_destroy(rwlock);
		free(rwlock);
	}
}

#endif
